﻿using UnityEditor;
using System;
using System.IO;
using System.Extension;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;

public class XMLAccessories
{
    [MenuItem("Assets/Create/XML/ObjectTemplate")]
    static void CreateXMLObjectTemplate()
    {
        List<string> filesPath = new List<string>();
        for (int i = 0; i < Selection.instanceIDs.Length; i++)
        {
            string fileName, newFilePath;
            SetNewLocations(i, out fileName, out newFilePath);

            filesPath.Add(newFilePath);
            Type type = TypeExtension.GetType(fileName);
            CreateObjectTemplate(type, newFilePath);
        }
        AssetDatabase.Refresh();
        Selection.objects = filesPath.Select(file => AssetDatabase.LoadAssetAtPath(file, typeof(TextAsset))).ToArray();
    }

    private static void CreateObjectTemplate(Type type, string path)
    {
        object obj = GetDefaultNewObject(type);
        Synchronise.SaveAsXML(obj, type, path);
    }

    [MenuItem("Assets/Create/XML/ListTemplate")]
    static void CreateXMLListTemplate()
    {
        List<string> filesPath = new List<string>();
        for (int i = 0; i < Selection.instanceIDs.Length; i++)
        {
            string fileName, newFilePath;
            SetNewLocations(i, out fileName, out newFilePath, true);

            filesPath.Add(newFilePath);
            Type type = TypeExtension.GetType(fileName);
            CreateListTemplate(type, newFilePath);
        }
        AssetDatabase.Refresh();
        Selection.objects = filesPath.Select(file => AssetDatabase.LoadAssetAtPath(file, typeof(TextAsset))).ToArray();
    }

    private static void SetNewLocations(int i, out string fileName, out string newFilePath, bool makePlural = false)
    {
        string path = AssetDatabase.GetAssetPath(Selection.instanceIDs[i]);
        string rootPath = Path.GetDirectoryName(path);
        fileName = Path.GetFileNameWithoutExtension(path);
        newFilePath = rootPath + "/" + ( makePlural ? fileName.ToPlural() : fileName ) + ".xml";
    }

    static void CreateListTemplate(Type type, string path)
    {
        IList list = GetDefaultList(type);
        var listType = typeof(List<>);
        //var constructedListType = listType.MakeGenericType(type);
        Synchronise.SaveAsXML(list, listType.MakeGenericType(type), path);
    }

    static IList GetDefaultList(Type t)
    {
        var listType = typeof(List<>);
        var constructedListType = listType.MakeGenericType(t);

        IList instance = (IList)Activator.CreateInstance(constructedListType);
        instance.Add(GetDefaultNewObject(t));
        instance.Add(GetDefaultNewObject(t));
        return instance;
    }

    public static object GetDefaultNewObject(Type t, string value = "Default")
    {
        object result = null;
        try
        {
            result = t.GetConstructor(new Type[] { }).Invoke(new object[] { });
            result.ForEachFieldInfo(m =>
            {
                try
                {
                    object defaultValue = 0;
                    if (m.FieldType.Equals(typeof(string)))
                        defaultValue = value;
                    else if (m.FieldType.IsGenericType)
                        defaultValue = GetDefaultList(TypeExtension.GetType(m.FieldType.ToString().GetStringBetween("[", "]")));
                    else if (m.FieldType.IsClass)
                        defaultValue = GetDefaultNewObject(m.FieldType);
                    m.SetValue(result, defaultValue);
                }
                catch { }
            });
        }
        catch { }
        return result;
    }
}
 /*  
   static T NewObject<T>(string value) where T : new()
   {
       T t = new T();
       t.ForEachFieldInfo(m =>
       {
           Debug.Log("Name : " + m.Name);
           try
           {
               m.SetValue(t, value);
           }
           catch { }
       });
       return t;
   }

   static void CreateTemplate<T>(string path) where T : new()
   {
       List<T> list = NewList<T>("Default");
       Synchronise.SaveAsXML<List<T>>(list, path);
   }

   static private List<T> NewList<T>(string value) where T : new()
   {
       List<T> list = new List<T>();
       T t = NewObject<T>(value);
       list.AddRange(new[] { t, t });
       return list;
   }
   */
